package org.chs.ts.batch.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.chs.ts.base.batch.exec.entity.BatchClearBasicTaskExec;
import org.chs.ts.base.batch.exec.entity.BatchClearBasicTaskStepExec;
import org.chs.ts.base.batch.vo.entity.BatchExecReq;
import org.chs.ts.base.batch.vo.entity.BatchExecResp;
import org.chs.ts.base.common.util.XssFilterUtils;
import org.chs.ts.base.constant.CommonConstant;
import org.chs.ts.base.vo.Result;
import org.chs.ts.batch.constant.TaskStatusCodeEnum;
import org.chs.ts.batch.exception.TaskExecException;
import org.chs.ts.batch.factory.TaskExecFactory;
import org.chs.ts.batch.service.IBatchClearBasicTaskExecService;
import org.chs.ts.batch.thread.BatchThreadPoolProperties;
import org.chs.ts.batch.threadservice.BatchExecService;
import org.chs.ts.batch.util.ConvertToUtil;
import org.chs.ts.batch.util.TaskBuilder;

import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * @Compay 盛唐天行
 * @Author: wuwei
 * @Censor By wuwei
 * @Sence 2023/1/5 14:03
 * @Modify 2023/1/5 14:03
 * @Description
 */
@Api(tags = "跑批平台-处理控制器")
@RestController
@Slf4j
@RequestMapping("/batchExec")
public class BatchExecController {

    @Resource
    private IBatchClearBasicTaskExecService clearBasicTaskExecService;
    @Resource
    private BatchThreadPoolProperties batchThreadPoolProperties;


    @Resource
    private BatchExecService batchExecService;

    @Resource
    private TaskExecFactory taskExecFactory;

    @Resource
    private TaskBuilder taskBuilder;



    @ApiOperation(value = "跑批平台-获取线程池参数", notes = "线程池参数")
    @GetMapping("/getBatcThreadPoolProperties")
    public Result<String> getBatchThreadPoolProperties() {
        String namePrefix = batchThreadPoolProperties.getNamePrefix();
        return Result.ok(namePrefix);
    }

    @ApiOperation(value = "跑批平台-异步执行跑批操作", notes = "异步执行跑批操作")
    @PostMapping("/process")
    //public BatchExecResp process(@RequestBody BatchExecReq request) {
    public BatchExecResp process(@RequestParam() String taskExecId, @RequestParam() String snatchingMode) {
        BatchExecReq request = new BatchExecReq();
        request.setTaskExecId(XssFilterUtils.filterXss(taskExecId));
        request.setSnatchingMode(XssFilterUtils.filterXss(snatchingMode));
        BatchClearBasicTaskExec taskExecObj = clearBasicTaskExecService.getOne(new LambdaQueryWrapper<BatchClearBasicTaskExec>().eq(BatchClearBasicTaskExec::getTaskExecid, taskExecId));
        if (taskExecObj==null) {
            return new BatchExecResp(request.getTaskExecId(), CommonConstant.RTN_CODE_FAILED, "request 请求参数异常！ taskExecId 参数[" + request.getTaskExecId() + "]未获取有效待执行跑批任务清单[BatchClearBasicTaskExec]");
        }
        request.setTaskGroup(XssFilterUtils.filterXss(taskExecObj.getTaskGroup()));
        request.setExecDate(XssFilterUtils.filterXss(taskExecObj.getExecDate()));
        request.setBatchSysCode(XssFilterUtils.filterXss(taskExecObj.getBatchSysCode()));
        String startTime = ConvertToUtil.getRunningTime();
        BatchExecResp response;
        try {
            // 初始化参数
            request = taskExecFactory.initBatchExecReq(request);
            // 线程池 验证
            taskExecFactory.checkThreadPool();
            taskExecFactory.checkIsTaskRunningTime(request);
            BatchClearBasicTaskExec taskExec = taskExecFactory.doTaskExec(request.getBatchSysCode(), request.getTaskGroup(), request.getExecDate(), request.getTaskExecId(), request.getSnatchingMode());
            List<BatchClearBasicTaskStepExec> taskStepExecList = taskExecFactory.getTaskStepExecListByTaskExec(taskExec);
            //因清算执行时间比较长，页面请求调用清算时，采用异步调用，通过刷新页面获取执行结果
            batchExecService.asyncDoProcess(request, taskExec, taskStepExecList);
            response = new BatchExecResp(request.getBatchSysCode(),request.getTaskGroup(), request.getTaskId(), request.getTaskExecId(), "000000", "清算任务调用成功");
        } catch (TaskExecException e) {
            log.error("异步调用清算任务异常：");
            response = new BatchExecResp(request.getBatchSysCode(),request.getTaskGroup(), request.getTaskId(), request.getTaskExecId(), "999999", e.getMessage());
            return response;
        } catch (Exception e) {
            log.error("异步调用清算任务失败：");
            log.error(e.getMessage(), e);
            response = new BatchExecResp(request.getBatchSysCode(),request.getTaskGroup(), request.getTaskId(), request.getTaskExecId(), "999999", "清算任务调用失败" + e.getMessage());
            return response;
        }
        log.info("中间业务批量处理-异步执行跑批操作执行耗时:" + ConvertToUtil.getRunningTime(startTime));
        return response;
    }


    /**
     * 针对 当个任务重跑 需要在 跑批任务运行状态停止 。 且 执行线程池中不存在在执行的线程。
     */
    @ApiOperation(value = "跑批平台-异步执行指定跑批操作", notes = "异步执行跑批操作")
    @PostMapping("/processByTaskExecId")
    public BatchExecResp processByTaskExecId(@RequestParam() String taskExecId, @RequestParam() String snatchingMode) {
        BatchExecReq request = new BatchExecReq();
        request.setTaskExecId(XssFilterUtils.filterXss(taskExecId));
        request.setSnatchingMode(XssFilterUtils.filterXss(snatchingMode));
        // todo-wuwei getOne 测试点 如果 getOne 无返回记录 确认 是否 返回null
        BatchClearBasicTaskExec clearBasicTaskExec = clearBasicTaskExecService.getOne(new LambdaQueryWrapper<BatchClearBasicTaskExec>().eq(BatchClearBasicTaskExec::getTaskExecid, taskExecId));
        if (clearBasicTaskExec==null) {
            return new BatchExecResp(request.getTaskExecId(), CommonConstant.RTN_CODE_FAILED, "request 请求参数异常！ taskExecId 参数[" + request.getTaskExecId() + "]未获取有效待执行跑批任务清单[BatchClearBasicTaskExec]");
        }
        request.setBatchSysCode(XssFilterUtils.filterXss(clearBasicTaskExec.getBatchSysCode()));
        request.setTaskGroup(XssFilterUtils.filterXss(clearBasicTaskExec.getTaskGroup()));
        request.setExecDate(XssFilterUtils.filterXss(clearBasicTaskExec.getExecDate()));
        String startTime = ConvertToUtil.getRunningTime();
        if (!("redis".equals(request.getSnatchingMode().toLowerCase(Locale.ROOT)) || "database".equals(request.getSnatchingMode().toLowerCase(Locale.ROOT)))) {
            return new BatchExecResp(request.getBatchSysCode(),request.getTaskGroup(), request.getTaskId(), request.getTaskExecId(), CommonConstant.RTN_CODE_FAILED, "request 请求参数异常！ snatchingMode 参数[" + request.getSnatchingMode() + "]不合法！有效参数为redis、database");
        }
        BatchExecResp response;
        try {
            // 初始化参数
            request = taskExecFactory.initBatchExecReq(request);
        } catch (TaskExecException e) {
            //e.printStackTrace();
            log.info(e.getMessage());
            response = new BatchExecResp(request.getBatchSysCode(),request.getTaskGroup(), request.getTaskId(), request.getTaskExecId(), CommonConstant.RTN_CODE_FAILED, "初始化 batchExecReq 对象");
            return response;
        }
        // 先判断 当前 是否 存在 redis 执行分布式锁
        // 如果存在 终止当前请求 反馈错误
        try {
            taskExecFactory.checkIsTaskRunningTime(request);
            //response = new BatchExecResp(request.getTaskGroup(), request.getTaskId(), request.getTaskExecId(), RetCode.FAILED, "当前 存在跑批任务[redis]执行分布式锁！请先关闭跑批任务执行分布式锁！");
            response = new BatchExecResp(request.getBatchSysCode(),request.getTaskGroup(), request.getTaskId(), request.getTaskExecId(), CommonConstant.RTN_CODE_FAILED, "当前 存在跑批任务[redis]执行分布式锁！请先关闭跑批任务执行分布式锁！");
            log.info("当前 存在跑批任务[redis]执行分布式锁！请先关闭跑批任务执行分布式锁！");

            return response;
        } catch (TaskExecException e) {
            log.info("taskExecFactory.checkIsTaskRunningTime 运行异常！" + e.getMessage());
        }
        try {
            // 验证 当前 是否 存在运行中的线程 .
            if (taskExecFactory.getThreadPoolRuningCount() > 0) {
                // 当前存在执行的线程 不允许开启 跑批任务
                throw new TaskExecException("当前跑批线程池存在执行中的任务[" + taskExecFactory.getThreadPoolRuningCount() + "],请稍后再试！", TaskStatusCodeEnum.TASK_ERROR, "");
            }
            BatchClearBasicTaskExec taskExec = taskExecFactory.doTaskExecByTaskExecId(request.getBatchSysCode(), request.getTaskGroup(), request.getExecDate(), request.getTaskExecId(), request.getSnatchingMode());
            List<BatchClearBasicTaskStepExec> taskStepExecList = taskExecFactory.getTaskStepExecListByTaskExec(taskExec);
            //因清算执行时间比较长，页面请求调用清算时，采用异步调用，通过刷新页面获取执行结果
            batchExecService.asyncDoProcess(request, taskExec, taskStepExecList);
            response = new BatchExecResp(request.getBatchSysCode(),request.getTaskGroup(), request.getTaskId(), request.getTaskExecId(), "000000", "清算任务调用成功");
        } catch (TaskExecException taskExecException) {
            log.error("异步调用清算任务异常：");
            response = new BatchExecResp(request.getBatchSysCode(),request.getTaskGroup(), request.getTaskId(), request.getTaskExecId(), "999999", taskExecException.getMessage());
        } catch (Exception ex) {
            log.error("异步调用清算任务失败：");
            log.error(ex.getMessage(), ex);
            response = new BatchExecResp(request.getBatchSysCode(),request.getTaskGroup(), request.getTaskId(), request.getTaskExecId(), "999999", "清算任务调用失败" + ex.getMessage());
        }
        log.info("中间业务批量处理-异步执行跑批操作执行耗时:" + ConvertToUtil.getRunningTime(startTime));
        return response;
    }

    @ApiOperation(value = "跑批平台-跑批抢夺操作", notes = "跑批抢夺操作")
    @PostMapping("/getTask")
    public Result<BatchExecResp> getTask(@RequestParam() String batchSysCode, @RequestParam() String taskGroup, @RequestParam() String execDate, @RequestParam() String snatchingMode) {
        BatchExecReq request = new BatchExecReq();
        request.setTaskGroup(XssFilterUtils.filterXss(taskGroup));
        request.setExecDate(XssFilterUtils.filterXss(execDate));
        request.setSnatchingMode(XssFilterUtils.filterXss(snatchingMode));
        request.setBatchSysCode(XssFilterUtils.filterXss(batchSysCode));

        String startTime = ConvertToUtil.getRunningTime();
        boolean result = false;
        String errMsg = "";
        BatchExecResp resq;
        if (!("redis".equals(request.getSnatchingMode().toLowerCase(Locale.ROOT)) || "database".equals(request.getSnatchingMode().toLowerCase(Locale.ROOT)))) {
            return Result.error("request 请求参数异常！ snatchingMode 参数[" + request.getSnatchingMode() + "]不合法！有效参数为redis、database");
        }
        try {
            // 验证 execDate 有效性
            taskExecFactory.checkExecDate(request.getExecDate());
            taskExecFactory.checkIsTaskRunningTime(request);
            BatchClearBasicTaskExec clearBasicTaskExec = taskExecFactory.getTaskExec(request.getBatchSysCode(), request.getTaskGroup(), request.getExecDate(), StringUtils.hasLength(request.getTaskExecId()) ? request.getTaskExecId() : "", request.getSnatchingMode());
            if (clearBasicTaskExec == null) {
                errMsg = "获取跑批抢夺操作失败！";
                String rtnCode = "999999";
                // 增加了 对 当前执行列表判断是否已终止完毕
                if (taskExecFactory.checkTaskExecEnd(request.getBatchSysCode(), request.getTaskGroup(), request.getExecDate(), request.getSnatchingMode())) {
                    errMsg = "执行跑批任务完成！";
                    rtnCode = "111111";
                }
                resq = new BatchExecResp(rtnCode, errMsg);
            } else {
                result = true;
                resq = new BatchExecResp(clearBasicTaskExec, "000000", "清算任务调用成功");
            }
        } catch (TaskExecException e) {
            errMsg = e.getMessage();
            resq = new BatchExecResp("111111", e.getMessage());
            return Result.error(errMsg, resq);
        } catch (Exception e) {
            log.error("异步调用清算任务失败：");
            log.error(e.getMessage(), e);
            errMsg = e.getMessage();
            resq = new BatchExecResp("999999", e.getMessage());
            return Result.error(errMsg, resq);
        }
        log.info("跑批平台-跑批抢夺操作执行耗时:" + ConvertToUtil.getRunningTime(startTime));
        if (result) {
            return Result.ok(resq);
        } else {
            return Result.error(errMsg, resq);
        }
    }

    @ApiOperation(value = "跑批平台-初始化跑批任务", notes = "初始化跑批任务")
    @PostMapping("/initTask")
    public Result<String> initTask(@RequestParam() String batchSysCode,@RequestParam() String taskGroup, @RequestParam() String execDate, @RequestParam() String snatchingMode) {
        BatchExecReq request = new BatchExecReq();
        request.setTaskGroup(XssFilterUtils.filterXss(taskGroup));
        request.setExecDate(XssFilterUtils.filterXss(execDate));
        request.setSnatchingMode(XssFilterUtils.filterXss(snatchingMode));
        request.setBatchSysCode(XssFilterUtils.filterXss(batchSysCode));
        String startTime = ConvertToUtil.getRunningTime();
        boolean result = false;
        String errMsg;
        if (!(StringUtils.hasLength(request.getBatchSysCode()) && StringUtils.hasLength(request.getTaskGroup()) && StringUtils.hasLength(request.getSnatchingMode()) && StringUtils.hasLength(request.getExecDate()))) {
            return Result.error("request 请求参数异常！batchSysCode or taskGroup or snatchingMode or taskDate is null");
        }
        try {
            // 验证 execDate 有效性
            taskExecFactory.checkExecDate(request.getExecDate());
            // 未获取异常 代表 当前执行状态。无法进行重置操作
            taskExecFactory.checkIsTaskRunningTime(request);
            //errMsg = "跑批任务 taskGroup[" + request.getTaskGroup() + "] execDate[" + request.getExecDate() + "] 运行中！无法进行初始化操作！";
        } catch (TaskExecException e) {
            //e.printStackTrace();
            log.info("跑批任务状态确认成功，当前无跑批任务运行！");
        }
        try {
            if (taskExecFactory.initTask(request)) {
                result = true;
                errMsg = "初始化跑批任务成功";
            }else{
                errMsg = "初始化跑批任务失败";

            }
            //errMsg = "初始化跑批任务失败";
        } catch (TaskExecException e) {
            log.error("初始化跑批任务异常：" + e.getMessage());
            errMsg = e.getMessage();
            return Result.error(errMsg);

        } catch (Exception e) {
            log.error("初始化跑批执行异常：" + e.getMessage());
            log.error(e.getMessage(), e);

            errMsg = e.getMessage();
            return Result.error(errMsg);
        }
        log.info("跑批平台-初始化跑批任务执行耗时:" + ConvertToUtil.getRunningTime(startTime));

        if (result) {
            return Result.ok(errMsg);
        } else {
            return Result.error(errMsg);
        }
    }

    @ApiOperation(value = "跑批平台-重置跑批任务", notes = "重置跑批任务将所有已生成任务删除后，重新生成跑批任务清单")
    @PostMapping("/resetTask")
    public Boolean resetTask(@RequestParam() String batchSysCode,@RequestParam() String taskGroup, @RequestParam() String execDate, @RequestParam() String snatchingMode) {
        BatchExecReq request = new BatchExecReq();
        request.setBatchSysCode(XssFilterUtils.filterXss(batchSysCode));
        request.setTaskGroup(XssFilterUtils.filterXss(taskGroup));
        request.setExecDate(XssFilterUtils.filterXss(execDate));
        request.setSnatchingMode(XssFilterUtils.filterXss(snatchingMode));
        String startTime = ConvertToUtil.getRunningTime();

        boolean result = false;
        String errMsg;

        try {
            taskExecFactory.checkIsTaskRunningTime(request);
            errMsg = "跑批平台-重置跑批任务执行存在redis执行全局锁";
            log.error(errMsg);
            log.info("跑批平台-重置跑批任务执行耗时:" + ConvertToUtil.getRunningTime(startTime));
            return false;
        } catch (TaskExecException e) {
            //log.info("taskExecFactory.checkIsTaskRunningTime 运行异常！" + e.getMessage());
        }

        try {
            //errMsg = "重置跑批任务失败";
            // 验证 execDate 有效性
            taskExecFactory.checkExecDate(request.getExecDate());
            // 验证 当前 是否 存在运行中的线程
            if (taskExecFactory.getThreadPoolRuningCount() > 0) {
                // 当前存在执行的线程 不允许开启 跑批任务
                throw new TaskExecException("当前跑批线程池存在执行中的任务[" + taskExecFactory.getThreadPoolRuningCount() + "],请稍后再试！", TaskStatusCodeEnum.TASK_ERROR, "");
            }
            taskExecFactory.forceToStopTaskRunningTime(request);

            if (taskExecFactory.resetTask(request)) {
                result = true;
                errMsg = "重置跑批任务成功";
                log.info(errMsg);
                //return Result.ok("重置跑批任务成功");
            }

            //return Result.error("重置跑批任务失败");

        } catch (TaskExecException e) {
            errMsg = e.getMessage();
            log.info(errMsg);
            return false;

            //return Result.error(e.getMessage());

        } catch (Exception e) {
            log.error("重置跑批任务：");
            log.error(e.getMessage(), e);
            errMsg = e.getMessage();
            log.info(errMsg);
            return result;

            //return Result.error(e.getMessage());
        }

        log.info("跑批平台-重置跑批任务执行耗时:" + ConvertToUtil.getRunningTime(startTime));

        return result;
    }

    @ApiOperation(value = "跑批平台-获取跑批状态", notes = "跑批平台-获取跑批状态")
    @PostMapping("/getTaskRunningStatus")
    public Boolean getTaskRunningStatus(@RequestParam() String batchSysCode, @RequestParam() String taskGroup, @RequestParam() String execDate, @RequestParam() String snatchingMode) {
        BatchExecReq request = new BatchExecReq();
        request.setBatchSysCode(XssFilterUtils.filterXss(batchSysCode));
        request.setTaskGroup(XssFilterUtils.filterXss(taskGroup));
        request.setExecDate(XssFilterUtils.filterXss(execDate));
        request.setSnatchingMode(XssFilterUtils.filterXss(snatchingMode));

        //String startTime = ConvertToUtil.getRunningTime();
        Boolean result;
        //String msg = "获取跑批状态成功，当前跑批任务";
        try {
            // 验证 execDate 有效性
            taskExecFactory.checkExecDate(request.getExecDate());
            result = taskExecFactory.getTaskRunningStatus(request);
        } catch (TaskExecException e) {
            throw new RuntimeException(e);
        }
        //log.info("中间业务批量处理-获取跑批状态执行耗时:" + ConvertToUtil.getRunningTime(startTime));
        return result;

    }

    @ApiOperation(value = "跑批平台-开启跑批任务", notes = "跑批平台-开启跑批任务")
    @PostMapping("/startTaskRunningStatus")
    public Boolean startTaskRunningStatus(@RequestParam() String batchSysCode, @RequestParam() String taskGroup, @RequestParam() String execDate, @RequestParam() String snatchingMode) {
        BatchExecReq request = new BatchExecReq();
        request.setBatchSysCode(XssFilterUtils.filterXss(batchSysCode));
        request.setTaskGroup(XssFilterUtils.filterXss(taskGroup));
        request.setExecDate(XssFilterUtils.filterXss(execDate));
        request.setSnatchingMode(XssFilterUtils.filterXss(snatchingMode));
        String startTime = ConvertToUtil.getRunningTime();
        boolean result = false;
        String msg;

//        if (!(StringUtils.hasLength(request.getTaskGroup()) && StringUtils.hasLength(request.getExecDate()))) {
//            return Result.error("request 请求参数异常！taskGroup  or taskDate is null");
//        }
        // 验证 execDate 有效性
        try {
            taskExecFactory.checkExecDate(request.getExecDate());
        } catch (TaskExecException e) {
            log.info("result:" + e.getMessage());
            return false;
        }
        try {
            // 未获取异常 代表 跑批任务未开启 可进行后续操作
            taskExecFactory.checkIsTaskRunningTime(request);
            msg = "开启跑批任务失败!跑批任务运行中";
            //result = false;
        } catch (TaskExecException e) {
            try {
                // 验证 当前 是否 存在运行中的线程
                if (taskExecFactory.getThreadPoolRuningCount() > 0) {
                    // 当前存在执行的线程 不允许开启 跑批任务
                    throw new TaskExecException("当前跑批线程池存在执行中的任务[" + taskExecFactory.getThreadPoolRuningCount() + "],请稍后再试！", TaskStatusCodeEnum.TASK_ERROR, "");
                }
                // wuwei@2023增加初始化执行计划 这里流程只新增不删除。如果已存在执行计划 不会对原执行计划进行修改
                try {
                    taskExecFactory.initTask(request);
                } catch (TaskExecException ex1) {
                    log.info("taskExecFactory.initTask 运行异常！" + ex1.getMessage());
                }
                taskExecFactory.startTaskRunning(request.getBatchSysCode(), request.getTaskGroup(), request.getExecDate());
                // wuw@20230703 修改 不在开启跑批状态时 新增待执行列表
                //taskExecFactory.insertTaskWaittingList(request.getTaskGroup(), request.getExecDate(), request.getSnatchingMode());
                result = true;
                msg = "开启跑批任务成功!";
            } catch (TaskExecException ex) {
                log.info(ex.getMessage());
                msg = ex.getMessage();
                log.info("result:" + msg);
                return false;
            }

        }
        log.info("result:" + msg);
        log.info("跑批平台-开启跑批任务:" + ConvertToUtil.getRunningTime(startTime));

        return result;

    }

    @ApiOperation(value = "跑批平台-停止跑批任务", notes = "跑批平台-停止跑批任务")
    @PostMapping("/stopTaskRunningStatus")
    public Boolean stopTaskRunningStatus(@RequestParam() String batchSysCode, @RequestParam() String taskGroup, @RequestParam() String execDate, @RequestParam() String snatchingMode) {
        BatchExecReq request = new BatchExecReq();
        request.setBatchSysCode(XssFilterUtils.filterXss(batchSysCode));
        request.setTaskGroup(XssFilterUtils.filterXss(taskGroup));
        request.setExecDate(XssFilterUtils.filterXss(execDate));
        request.setSnatchingMode(XssFilterUtils.filterXss(snatchingMode));
        String startTime = ConvertToUtil.getRunningTime();
        boolean result = false;
        String msg = "关闭跑批任务失败!";
        if (!(StringUtils.hasLength(request.getBatchSysCode()) && StringUtils.hasLength(request.getTaskGroup()) && StringUtils.hasLength(request.getExecDate()))) {
            return false;
        }
        // 验证 execDate 有效性
        try {
            taskExecFactory.checkExecDate(request.getExecDate());
        } catch (TaskExecException e) {
            log.info("result:" + e.getMessage());
            return false;
        }
        try {
            // 未获取异常 代表 跑批任务未开启 可进行后续操作
            taskExecFactory.checkIsTaskRunningTime(request);
            taskExecFactory.stopTaskRunning(request.getBatchSysCode(), request.getTaskGroup(), request.getExecDate());
            // wuw@20230703 修改 不在关闭跑批状态时 删除待执行列表
            //taskExecFactory.delTaskWaittingValue(request.getTaskGroup(), request.getExecDate(), request.getSnatchingMode());
            result = true;
            msg = "关闭跑批任务成功!";
            if (taskExecFactory.getThreadPoolRuningCount() > 0) {
                // 当前存在执行的线程 不允许开启 跑批任务
                msg += "当前跑批线程池存在执行中的任务[" + taskExecFactory.getThreadPoolRuningCount() + "]";
            }
        } catch (TaskExecException e) {
            msg += "跑批任务未开启！";
        }
        log.info("跑批平台-关闭跑批任务:" + msg + " 操作耗时：" + ConvertToUtil.getRunningTime(startTime));
        return result;
    }

    @ApiOperation(value = "跑批平台-获取待执行跑批计划列表", notes = "待执行跑批计划列表")
    @PostMapping("/getTaskWaittingList")
    public BatchExecReq getTaskWaittingList(@RequestParam() String batchSysCode, @RequestParam() String taskGroup, @RequestParam() String execDate) {
        BatchExecReq request = new BatchExecReq();
        request.setTaskGroup(XssFilterUtils.filterXss(taskGroup));
        request.setExecDate(XssFilterUtils.filterXss(execDate));
        request.setBatchSysCode(XssFilterUtils.filterXss(batchSysCode));
        String taskWaittingValue = taskExecFactory.getTaskWaittingValue(request);
        String[] taskWaitting = taskWaittingValue.isEmpty() ? new String[]{} : taskWaittingValue.split("_");
        BatchExecReq batchExecReq = new BatchExecReq();
        if (taskWaitting.length == 0) {
            return batchExecReq;
        }
        batchExecReq.setTaskGroup(taskWaitting[0]);
        batchExecReq.setExecDate(taskWaitting[1]);
        batchExecReq.setSnatchingMode(taskWaitting[2]);
        return batchExecReq;
    }

    @ApiOperation(value = "跑批平台-确认待执行跑批计划列表", notes = "待执行跑批计划列表")
    @PostMapping("/confirmTaskWaitting")
    public boolean confirmTaskWaitting(@RequestParam() String batchSysCode, @RequestParam() String taskGroup, @RequestParam() String execDate, @RequestParam() String snatchingMode) {
        BatchExecReq request = new BatchExecReq();
        request.setBatchSysCode(XssFilterUtils.filterXss(batchSysCode));
        request.setTaskGroup(XssFilterUtils.filterXss(taskGroup));
        request.setExecDate(XssFilterUtils.filterXss(execDate));
        request.setSnatchingMode(XssFilterUtils.filterXss(snatchingMode));
        return taskExecFactory.confirmTaskWaittingValue(request);
    }

    @ApiOperation(value = "跑批平台-确认是否存在待执行列表", notes = "确认是否存在待执行列表(数据库)")
    @PostMapping("/checkTaskWaittingValue")
    public boolean checkTaskWaittingValue(@RequestParam() String batchSysCode, @RequestParam() String taskGroup, @RequestParam() String execDate) {
        return taskExecFactory.checkTaskWaittingValue(XssFilterUtils.filterXss(batchSysCode), XssFilterUtils.filterXss(taskGroup), XssFilterUtils.filterXss(execDate));
    }


    @ApiOperation(value = "跑批平台-创建执行跑批计划列表", notes = "创建执行跑批计划列表")
    @PostMapping("/createTaskWaittingList")
    public boolean createTaskWaittingList(@RequestParam() String batchSysCode, @RequestParam() String taskGroup, @RequestParam() String execDate, @RequestParam() String snatchingMode) {
        BatchExecReq request = new BatchExecReq();
        // 针对 taskGroup 批量支持
        //request.setTaskGroup(taskGroup);
        String[] taskGroupList = taskGroup.split("_");
        Map<String, Boolean> taskGrorupMap = new HashMap<>();
        request.setBatchSysCode(batchSysCode);
        request.setExecDate(execDate);
        request.setSnatchingMode(snatchingMode);
        // 验证 execDate 有效性
        try {
            taskExecFactory.checkExecDate(request.getExecDate());
        } catch (TaskExecException e) {
            log.info("result:" + e.getMessage());
            return false;
        }
        for (String taskGroupItem : taskGroupList) {
            request.setTaskGroup(taskGroupItem);
            // 增加自动重发
            boolean result;
            int i = 0;
            do {
                result = taskExecFactory.insertTaskWaittingList(request.getBatchSysCode(),request.getTaskGroup(), request.getExecDate(), request.getSnatchingMode());
                if (i > 3) {
                    break;
                }
                i++;

            } while (!result);
            // 增加验证是否创建成功
            String taskWaittingValue = taskExecFactory.getTaskWaittingValue(request);
            String[] taskWaitting = taskWaittingValue.isEmpty() ? new String[]{} : taskWaittingValue.split("_");
            taskGrorupMap.put(taskGroupItem, !(taskWaitting.length == 0));
            //log.info("中间业务批量处理-创建执行跑批计划列表:taskGroup -> " + taskGroup + " execDate -> " + execDate + " snatchingMode -> " + snatchingMode + " 创建结果:" + !(taskWaitting.length == 0));
        }
        // 验证 批量执行结果
        boolean runingResult = true;
        for (String key : taskGrorupMap.keySet()) {
            if (!taskGrorupMap.get(key)) {
                runingResult = false;
                break;
            }
        }

        return runingResult;

    }

    //@ApiOperation(value = "跑批平台-处理资金交易对账差错", notes = "处理资金交易对账差错")
    //@PostMapping("/optTradeCapitalCheckError")
    //public boolean optTradeCapitalCheckError(@RequestParam() String errorSerno, @RequestParam() String optDealStatus, @RequestParam(required = false) String optDealSummary) {
    //    // 差错状态 1 线上处理 2 线下处理
    //    if (!(optDealStatus.equals(EnumUtil.资金交易对账差错表_差错状态_人工线上处理) || optDealStatus.equals(EnumUtil.资金交易对账差错表_差错状态_人工线下处理))) {
    //        return false;
    //    }
    //    boolean result = taskExecFactory.optTradeCapitalCheckError(errorSerno, optDealStatus, optDealSummary);
    //    // 如果是线上处理 在更新完 资金对账差错流水后 ，异步执行 调账操作
    //    if (optDealStatus.equals(EnumUtil.资金交易对账差错表_差错状态_人工线上处理) && result) {
    //        batchExecService.asyncDoTradeCapitalCheckError(errorSerno);
    //    }
    //    return result;
    //}

    @ApiOperation(value = "跑批平台-获取跑批日期", notes = "跑批平台-获取跑批日期")
    @PostMapping("/getExeDate")
    public String getExeDate() {
        String startTime = ConvertToUtil.getRunningTime();

        log.info("跑批平台-获取跑批日期开始");
        String mwbpTransDay = taskBuilder.getDayBy(-1);
        log.info("跑批平台-获取跑批日期结束 操作耗时：" + ConvertToUtil.getRunningTime(startTime));

        return mwbpTransDay;
    }

    //@ApiOperation(value = "跑批平台-提醒客户未提货短信发送手工处理", notes = "跑批平台-提醒客户未提货短信发送手工处理")
    //@PostMapping("/noteSendToUser")
    //public String noteSendToUser() {
    //    log.info("手动执行批量发送提货短信提醒开始");
    //    noteBatchTaskService.process();
    //    log.info("手动执行批量发送提货短信提醒结束");
    //    return "OK";
    //}
}
